#include "../NewSyndrome-module.h"
#include "auth-public.h"
#include <stdlib.h>
#include <time.h>

#define LOG_DEFAULT_PATH "modules/logs/"
#define LOG_NB_HIDED_CMD 9

enum { LOG_NICK, LOG_QUIT };

char *path = NULL;
void get_path_from_conf (void);
conf *bot_info;

void
module_init (void)
{
  bot_set_auteur_module ("Thaeron");
  bot_set_desc_module ("log");
  bot_set_ident_module ("log");
  bot_set_version_module ("0.3");

  bot_add_type_handler ("PRIVMSG", "log_it");
  bot_add_type_handler ("NOTICE", "log_it");
  bot_add_type_handler ("JOIN", "log_it");
  bot_add_type_handler ("PART", "log_it");
 
  bot_add_type_handler ("QUIT", "log_nick_quit");
  bot_add_type_handler ("NICK", "log_nick_quit");
	
  bot_add_type_handler ("MODE", "log_it");
  bot_add_type_handler ("TOPIC", "log_it");
  bot_add_type_handler ("KICK", "log_it");

  bot_info = bot_conf_get_addr ();
  get_path_from_conf ();
}

#ifdef WIN32
void
init_dep (char *nom, void *addr)
{
  init_share_dep (nom, addr);
}
#endif

void
module_signal (byte sig, char *tab[], int nb)
{
  int a;
  if (sig == UNLOAD)
    {
      for (a = 0; a < nb; a++)
	if (!strcmp (tab[a], "log"))
	  if (path)
	    free (path);
    }
}


void
get_path_from_conf (void)
{
  int n;
  char car_tmp;	
	
  path = bot_get_info_from_conf ("log_path", 1);
  if (!path)
      path = strdup (LOG_DEFAULT_PATH);
  else
  {
      n = strlen (path);
      car_tmp = path[n - 1];

#ifdef WIN32
      if (car_tmp != '\\' && car_tmp != '/')
      {
		path = (char *) realloc (path, n + 2);
		strcpy (path + n, "\\");
      }
#else
      if (car_tmp != '/')
      {
		path = (char *) realloc (path, n + 2);
		strcpy (path + n, "/");
      }
#endif
    }
}


void
tmin (char *strmaj, char *strmin)
{				/* converti majuscule -> minuscule */
  unsigned int a = 0;
  for (; strmaj[a] != 0; a++)
    {
      if ((strmaj[a] >= 65) && (strmaj[a] <= 90))
	strmin[a] = strmaj[a] + 32;
      else
	strmin[a] = strmaj[a];
    }
  strmin[a] = 0;
}

void
put_all_args (msg * i, FILE * f, int depart)
{
  int r;
  for (r = depart; r < i->nbarg; r++)
    {
      fputs (i->argu[r], f);
      if (r + 1 < i->nbarg)
	fputs (" ", f);
    }
}


FILE *log_open_log (char *buffer, char *time_full)
{
    FILE *f;
    
    f = fopen (buffer, "r");
    if (!f)
    {
      f = fopen (buffer, "a+");
      if (!f)
	{
	  f = fopen (buffer, "w");
	  if (!f)
		return (NULL);
	}
      fprintf (f, "**** DEBUT DU LOG A %s\n\n", time_full);
    }
  else
    {
      fclose (f);
      f = fopen (buffer, "a+");
      if (!f)
		return (NULL);
    }
    return (f);
}

char *log_make_time (char *timz, char *time_full)
{
  char *time_now = timz;
  time_t toow = time (NULL);
 
  snprintf (timz, 29, "%s", asctime (localtime (&toow)));
  timz[29] = 0;
  strcpy (time_full, timz);
	
  time_now += 4;
  time_now[strlen (time_now) - 6] = 0;
	
  return (time_now);
}

int log_nick_quit (msg *i)
{
	FILE *f;
	char timz[30], time_full[30];
	char  **cl, *time_now, *mib, *buffer;
	int type, w;
	
	time_now = log_make_time (timz, time_full);	

	type = LOG_QUIT;
	mib = i->sender_nick;
	
	if (!strcasecmp (i->cmd, "NICK"))
	{
		mib = i->dest;
		type = LOG_NICK;
	}
	
	cl = bot_get_chanlist (mib);
	if (!cl)
	{
		log_module_infof ("Erreur (grave) : bot_get_chanlist(%s) => NULL", mib);
		return (0);
	}
		
		
	for (w = 0; cl[w]; w++)
	{
		mib = (char *) malloc (strlen (cl[w]) + 1);
		tmin (cl[w], mib);
		buffer = strf ("%s%s-%s.log", path, bot_info->server, mib);
		free (mib);
		f = log_open_log (buffer, time_full);
		free (buffer);
		if (!f)
			continue;
		if (type == LOG_NICK)
			fprintf (f, "%s ---\t%s is now known as %s\n", time_now, i->sender_nick, i->dest);
		
		else
		{
			fprintf (f, "%s <--\t%s (%s@%s) has quit (",  time_now, i->sender_nick, i->sender_ident, i->sender_host);
			if (i->raw_txt)
				fputs (i->raw_txt, f);
			fputs (")\n", f);
			
			if (is_botnick (i->sender_nick))
				fprintf (f, "**** FIN DU LOG A %s\n\n", time_full);
		}

		fclose (f);
	}
	free (cl);		
	
	return (0);
}


int log_it (msg * i)
{
  char hided_cmd[LOG_NB_HIDED_CMD][13] = {{"auth"},{"admin"},{"chgpass"},{"adduser"},{"addchan"},
					{"friendbot"},{"addadmin"},{"chgadminpass"},{"raw"}};
	
  FILE *f;
  char timz[30], time_full[30];
  char *buffer, *mib, *time_now;
  int w;

 
  if (!is_botnick (i->dest))
    {
      mib = (char *) malloc (strlen (i->dest) + 1);
      tmin (i->dest, mib);
    }
  else
    {
      mib = (char *) malloc (strlen (i->sender_nick) + 1);
      tmin (i->sender_nick, mib);
    }

  buffer = strf ("%s%s-%s.log", path, bot_info->server, mib);
  free (mib);

  time_now = log_make_time (timz, time_full);
    
  f = log_open_log (buffer, time_full);
  free (buffer);
  if (!f)
	return (0);

   if (!strcasecmp (i->cmd, "JOIN"))
    {
      if (is_botnick (i->sender_nick))
	fprintf (f, "**** DEBUT DU LOG A %s\n\n", time_full);

      fprintf (f, "%s -->\t%s (%s@%s) has joined %s\n", time_now, i->sender_nick, i->sender_ident, i->sender_host, i->dest);
    }

  else if (!strcasecmp (i->cmd, "PRIVMSG"))
    {
      fprintf (f, "%s <%s>\t", time_now, i->sender_nick);
      if ((i->nbarg > 0) && (is_botnick (i->dest)))
	{
	  for (w = 0; w < LOG_NB_HIDED_CMD; w++)
		if (!strcasecmp (i->argu[0], hided_cmd[w]))
		{
			fputs (hided_cmd[w], f);
			fputs (" xxxxxxxxxxxx\n", f);
			fclose (f);
			return (0);
		}
	}
      if (i->raw_txt)
		fputs (i->raw_txt, f);
      fputc ('\n', f);
    }

  else if (!strcasecmp (i->cmd, "NOTICE"))
    {
      fprintf (f, "%s >%s<\t", time_now, i->sender_nick);
      if (i->raw_txt)
		fputs (i->raw_txt, f);
      fputc ('\n', f);
    }

  else if (!strcasecmp (i->cmd, "PART"))
    {
      fprintf (f, "%s <--\t%s (%s@%s) has left %s (", time_now, i->sender_nick, i->sender_ident, i->sender_host, i->dest);
      if (i->raw_txt)
		fputs (i->raw_txt, f);
      fputs (")\n", f);
      if (is_botnick (i->sender_nick))
	fprintf (f, "**** FIN DU LOG A %s\n\n", time_full);
    }

  else if (!strcasecmp (i->cmd, "MODE"))
    {
      if (!strcasecmp (i->argu[0], "+o"))
	fprintf (f, "%s ---\t%s gives channel operator status to %s\n", time_now, i->sender_nick, i->argu[1]);
      
      else if (!strcasecmp (i->argu[0], "-o"))
	fprintf (f, "%s ---\t%s removes channel operator status from %s\n", time_now, i->sender_nick, i->argu[1]);

      else if (!strcasecmp (i->argu[0], "-v"))
	fprintf (f, "%s ---\t%s removes voice from %s\n", time_now, i->sender_nick, i->argu[1]);
      
      else if (!strcasecmp (i->argu[0], "+v"))
	fprintf (f, "%s ---\t%s gives voice to %s\n", time_now, i->sender_nick, i->argu[1]);

      else if (!strcasecmp (i->argu[0], "+h"))
	fprintf (f, "%s ---\t%s gives channel half-operator status to %s\n", time_now, i->sender_nick, i->argu[1]);
      
      else if (!strcasecmp (i->argu[0], "-h"))
	fprintf (f, "%s ---\t%s removes channel half-operator status from %s\n", time_now, i->sender_nick, i->argu[1]);

      else
	{
	  fprintf (f, "%s ---\t%s sets mode ", time_now, i->sender_nick);
	  if (i->raw_txt)
		fputs (i->raw_txt, f);
	  fprintf (f, " %s\n", i->dest);
	}

    }

  else if (!strcasecmp (i->cmd, "TOPIC"))
    {
      fprintf (f, "%s ---\t%s has changed the topic to: ",
	       time_now, i->sender_nick);

      if (i->raw_txt)
		fputs (i->raw_txt, f);
      fputc ('\n', f);
    }

  else if (!strcasecmp (i->cmd, "KICK"))
    {
      fprintf (f, "%s <--\t%s has kicked %s from %s (", time_now, i->sender_nick, i->argu[0], i->dest);
      if (i->nbarg >= 2)
	{
	  if (*i->argu[1] == ':')
	    fputs (i->argu[1] + 1, f);
	  else
	    fputs (i->argu[1], f);

	  if (i->nbarg > 2)
	    fputs (" ", f);
	}
      put_all_args (i, f, 2);
      fputs (")\n", f);
      if (is_botnick (i->argu[0]))
	fprintf (f, "**** FIN DU LOG A %s\n\n", time_full);
    }

  fclose (f);
  return 0;
}
